package control;

import java.util.Vector;

import javax.sql.rowset.CachedRowSet;

import parser.*;

import GDD.GDD;
import GDD.GFragment;
import GDD.GTable;
import NetWork.ResultSetScheduler;
import NetWork.SocketConnector;
import NetWork.TransmissionUtil;

public class VerticalDeleteThread extends Thread
{
	public int i;
	public GDD gdd;
	public Parser p;
	public SocketConnector clientConnector;
	VerticalDeleteThread(GDD g, int n, Parser parser){
		i = n;
		gdd = g;
		p = parser;	
		clientConnector = TransmissionUtil.getSharedTransmissionUtil().getConnectorByAddr(gdd.client.IP, gdd.client.port);
	}
	public void run(){
		String[] sites;
		String[] messages;
		Vector<String> directSites = new Vector<String>(0,gdd.tables.elementAt(i).fragments.size());;
		Vector<String> indirectSites = new Vector<String>(0,gdd.tables.elementAt(i).fragments.size());
		sites = new String[gdd.tables.elementAt(i).fragments.size()];
		messages = new String[sites.length];
		for (int j = 0; j < gdd.tables.elementAt(i).fragments.size(); j++)
		{
			sites[j] = gdd.tables.elementAt(i).fragments.elementAt(j).siteName;
			if(isDirectSite(gdd.tables.elementAt(i).fragments.elementAt(j),p.delete.leftOPs)==true){
				directSites.add(sites[j]);
			}
			else{
				indirectSites.add(sites[j]);
			}
		}
		//System.out.println("run test");
		//there is at least one indirectSite
		if(indirectSites.size()>0){
			//select
			String selectStatment = new String("select "+getSameAttribution(gdd.tables.elementAt(i))+" from "+gdd.tables.elementAt(i).tableName+" where "+p.delete.leftOPs[0]+p.delete.operators[0]+p.delete.rightOPs[0]);	
			for(int j=0; j<directSites.size(); j++){
				TransmissionUtil.getSharedTransmissionUtil().executeQuery(gdd.getSite(directSites.elementAt(j)), gdd.getSite(gdd.controlSite.siteName), selectStatment);
				Controller.deleteWait++;
			}
			//wait for the data
			//System.out.println("deleteWait = "+Controller.deleteWait);
			while(Controller.deleteWait>0);
			//System.out.println("exit delteWait");
			//delete
			String deleteStatment;
			String sameAtt = getSameAttribution(gdd.tables.elementAt(i));
			//only one direct site
			//System.out.println("rowset size: "+ResultSetScheduler.resultSetQueue.size());
			if(ResultSetScheduler.resultSetQueue.size()==1){
				//System.out.println("enter queue");
				CachedRowSet crs = ResultSetScheduler.resultSetQueue.poll();
				try{
					//System.out.println("row:"+crs.size()+"\ncolumn"+crs.getMetaData().getColumnCount());
					while(crs.next()){
						deleteStatment = new String("delete from "+p.delete.tableName+" where "+getSameAttribution(gdd.tables.elementAt(i))+" = "+crs.getString(sameAtt));
						//System.out.println("crs.size = "+crs.size()+"\n"+deleteStatment);
						for(int j=0; j<directSites.size(); j++){
							TransmissionUtil.getSharedTransmissionUtil().executeQuery(gdd.getSite(directSites.elementAt(j)), null, deleteStatment);
						}
						for(int j=0; j<indirectSites.size(); j++){
							TransmissionUtil.getSharedTransmissionUtil().executeQuery(gdd.getSite(indirectSites.elementAt(j)), null, deleteStatment);
						}
					}					                  					
				}catch(Exception e){
					//TODO deal with exception
				}
			}
		}//*/
		
		//involved sites
		String s = new String("The involved site: " + sites[0]);
		for (int j = 1; j < sites.length; j++)
		{
			s += ", " + sites[j];
		}
		//System.out.print("");
		// send to client site
		clientConnector.sendString("delete successfully", PConstants.CONSTROL_SITE);
		clientConnector.sendString(s, PConstants.CONSTROL_SITE);
		//for(int j=0; j<messages.length; j++){
			//clientConnector.sendString(messages[j], PConstants.CONSTROL_SITE);
		//}
		// System.out.print("");
	}

	public String getSameAttribution(GTable table){
		for(int i=0; i<table.attributions.length; i++){
			if(isOnAllFragments(table.attributions[i], table.fragments)==true){
				return table.attributions[i]; 
			}
		}
		return null;
	}
	public boolean isOnAllFragments(String attribution, Vector<GFragment> fragments){
		int count=0;
		for(int i=0; i<fragments.size(); i++){
			for(int j=0; j<fragments.elementAt(i).subAttributions.length; j++){
				if(attribution.compareToIgnoreCase(fragments.elementAt(i).subAttributions[j])==0){
					count++;
				}
			}
		}
		if(count == fragments.size())
			return true;
		return false;
	}
	public boolean isDirectSite(GFragment fragment, String []atts){
		if(atts.length==1){
			for(int i=0; i<fragment.subAttributions.length; i++){
				if(atts[0].compareToIgnoreCase(fragment.subAttributions[i])==0){
					return true;
				}
			}
		}
		return false;
	}

}
